#include "Common.h"
#include "Application.h"

#include "PSPGraphics.h"
#include "PSPTime.h"
#include "PSPInput.h"

#include <pspkernel.h>
#include <pspdebug.h>

namespace GenBen {

PSPGraphics* graphics = NULL;
PSPTime* time = NULL;
PSPInput* input = NULL;

void dump_threadstatus(void);

int done = 0;

/* Exit callback */
int exit_callback(int arg1, int arg2, void *common)
{
	done = 1;
	return 0;
}

/* Callback thread */
int CallbackThread(SceSize args, void *argp)
{
	int cbid;

	cbid = sceKernelCreateCallback("Exit Callback", exit_callback, NULL);
	sceKernelRegisterExitCallback(cbid);
	sceKernelSleepThreadCB();

	return 0;
}

/* Sets up the callback thread and returns its thread id */
int SetupCallbacks(void)
{
	int thid = 0;

	thid = sceKernelCreateThread("update_thread", CallbackThread,
				     0x11, 0xFA0, 0, 0);
	if(thid >= 0)
	{
		sceKernelStartThread(thid, 0, 0);
	}

	return thid;
}

void criticalError(string message)
{
	FILE* error_file = fopen("error.txt", "w");
	fprintf(error_file, message.c_str());
	fclose(error_file);
	exit(0);
}

Application::Application(const string& title, uint width, uint height, uint scale, bool fullscreen, bool lcd)
{
	//ASSERT(width == 480 && height == 272);
	//ASSERT(scale == 1);
	
	SetupCallbacks();
	
	time = new PSPTime();
}

Application::~Application()
{
	if(graphics) delete graphics;
	if(time) delete time;
	if(input) delete input;
	
	sceKernelExitGame();
}

void Application::run()
{
	init();

	while(!done)
	{
		time->update();
		if(input)
			input->update();

		update();
		render();		
	}

	close();
}

Graphics* Application::getGraphics()
{
	if(graphics == NULL)
		graphics = new PSPGraphics();

	return (Graphics*)graphics;
}

Input* Application::getInput()
{
	if(input == NULL)
		input = new PSPInput();

	return (Input*)input;
}

Time* Application::getTime()
{
	return (Time*)time;
}

}
